=pod
 * Import.pm
 * 
 * Copyright (C) 2012 Elena Shishkina
 * 
 * This file is part of ServerInventory.
 * 
 * ServerInventory is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ServerInventory is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ServerInventory.  If not, see <http://www.gnu.org/licenses/>.
=cut

use utf8;
use 5.12.0;
package ServerInventory::Import;
use Moose;
use DBI;
use JSON;
use Try::Tiny;

sub Process {
    my $self = shift;
    my $r = shift;
    $self->{request} = $r;
    $r->{dbh}->{AutoCommit} = 0;
    $r->{dbh}->{RaiseError} = 1;
    try {
        $r->{dbh}->do('delete from server_ips');
        $r->{dbh}->do('delete from reserved_units');
        $r->{dbh}->do('delete from inventory');
        $r->{dbh}->do('delete from racks');
        $r->{dbh}->do('delete from dcs');
        $r->{dbh}->do('delete from vendors;');
        $self->LoadVendors if $r->param('vendors');
        if ($r->param('datacenters')) {
            $self->LoadDataCenters;
        } else {
            $r->render(template => 'import');
            $r->{dbh}->rollback;
            return "Datacenters file hasn't provided";
        }
        if ($r->param('racks')) {
            $self->LoadRacks;
        } else {
            $r->render(template => 'import');
            $r->{dbh}->rollback;
            return "Racks file hasn't provided";
        }
        if ($r->param('servers')) {
            $self->LoadServers;
        } else {
            $r->render(template => 'import');
            $r->{dbh}->rollback;
            return "Servers file hasn't provided";
        }
        $r->{dbh}->commit;
        return "Finished";
    } catch {
        return $_;
    }
}

sub LoadVendors {
    my $self = shift;
    my $r = $self->{request};
    my $file = $r->req->upload('vendors')->slurp;
    my @lines = split /\r*\n/, $file;
    my $first = 1;
    my $sth = $r->{dbh}->prepare('insert or replace into vendors (name, color) values (?, ?)');
    for (@lines) {
        chomp;
        next if length($_) == 0;
        if ($first) { $first = 0; }
        else {
            my @cols = split /;/;
            $sth->execute(@cols);
        }
    }
}

sub LoadDataCenters {
    my $self = shift;
    my $r = $self->{request};
    my $file = $r->req->upload('datacenters')->slurp;
    my @lines = split /\r*\n/, $file;
    die 'Empty datacenters file' if @lines < 2;
    my $first = 1;
    my $sth = $r->{dbh}->prepare('insert or replace into dcs (name, address, power, notes) values (?, ?, ?, ?)');
    for (@lines) {
        chomp;
        next if length($_) == 0;
        if ($first) { $first = 0; }
        else {
            my @cols = split /;/, $_, -1;
            die 'Empty name in string ' . $cols[0] unless $cols[0];
            $cols[2] = undef unless $cols[2];
            $sth->execute(@cols);
        }
    }
}

sub LoadRacks {
    my $self = shift;
    my $r = $self->{request};
    my $file = $r->req->upload('racks')->slurp;
    my @lines = split /\r*\n/, $file;
    die 'Empty racks file' if @lines < 2;
    my $first = 1;
    #DC;Name;Vendor;Units;Notes;Responsible
    my $sth = $r->{dbh}->prepare('insert or replace into racks (dc_id, name, vendor_id, units, notes, responsible) values  (?, ?, ?, ?, ?, ?)');
    for (@lines) {
        chomp;
        next if length($_) == 0;
        if ($first) { $first = 0; }
        else {
            my @cols = split /;/, $_, -1;
            die 'Empty dc_name in string ' . $cols[0] unless $cols[0];
            die 'Empty name in string ' . $cols[1] unless $cols[1];
            die 'Empty units in string ' . $cols[3] unless $cols[3];
            my $sth1 = $r->{dbh}->prepare('select id from dcs where name = ?');
            $sth1->execute($cols[0]);
            my $dc = $sth1->fetchrow_array or die 'Can\'t find dc with name ' . $cols[0];
            $cols[0] = $dc;
            if ($cols[2]) {
                $sth1 = $r->{dbh}->prepare('select id from vendors where name = ?');
                $sth1->execute($cols[2]);
                my $id = $sth1->fetchrow_array;
                unless ($id) {
                    $sth1 = $r->{dbh}->prepare('insert into vendors (name) values (?); select max(id) from vendors;');
                    $sth1->execute($cols[2]);
                    $id = $sth1->fetchrow_array;
                }
                $cols[2] = $id;
            } else {
                $cols[2] = undef;
            }
            $sth->execute(@cols);
        }
    }
}

sub LoadServers {
    my $self = shift;
    my $r = $self->{request};
    my $file = $r->req->upload('servers')->slurp;
    my @lines = split /\r*\n/, $file;
    die 'Empty racks file' if @lines < 2;
    my $first = 1;
    #DataCenter;Rack;SrvName;Vendor;Type;Model;S/N;I/N;PowerUsage;PowerState;Units;SrvIP;MgmtIP;Notes;Color;Responsible
    # 0         1    2       3      4    5     6   7   8          9            10  11    12     13    14    15
    my $sth = $r->{dbh}->prepare('insert into inventory (rack_id, name, vendor_id, model, type, sn, [in], pusage, pstate, units, mgmtip, notes, color, responsible)  values  (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
    for (@lines) {
        chomp;
        next if length($_) == 0;
        if ($first) { $first = 0; }
        else {
            my @cols = split /;/, $_, -1;
            die 'Empty dc_name in string ' . $cols[0] unless $cols[0];
            die 'Empty rack_name in string ' . $cols[1] unless $cols[1];
            die 'Empty units in string ' . $cols[10] unless $cols[10];
            my $sth1 = $r->{dbh}->prepare('select id from dcs where name = ?');
            $sth1->execute($cols[0]);
            my $dc = $sth1->fetchrow_array or die 'Can\'t find dc with name ' . $cols[0];
            
            $sth1 = $r->{dbh}->prepare('select id from racks where dc_id = ? and name = ?');
            $sth1->execute($dc, $cols[1]);
            my $rack = $sth1->fetchrow_array or die 'Can\'t find rack ' . $cols[1] . ' in the dc ' . $cols[0];
            $cols[0] = $dc;
            $cols[1] = $rack;
            if ($cols[3]) {
                $sth1 = $r->{dbh}->prepare('select id from vendors where name = ?');
                $sth1->execute($cols[3]);
                my $id = $sth1->fetchrow_array;
                unless ($id) {
                    $sth1 = $r->{dbh}->prepare('insert into vendors (name) values (?); select max(id) from vendors;');
                    $sth1->execute($cols[3]);
                    $id = $sth1->fetchrow_array;
                }
                $cols[3] = $id;
            } else {
                $cols[3] = undef;
            }
            my $ips = splice(@cols, 11, 1);
            splice(@cols, 0, 1);
            $sth->execute(@cols);
            $sth1 = $r->{dbh}->prepare('select max(id) from inventory');
            $sth1->execute;
            my $id = $sth1->fetchrow_array;
            my @ips = split /,/, $ips;
            if (@ips) {
                $sth1 = $r->{dbh}->prepare('insert into server_ips (server_id, ip) values (?, ?)');
                for (@ips) {
                    $sth1->execute($id, $_);
                }
            }
        }
    }
}

1;

